package app.frames;

import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Set;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import libs.Attendance;
import libs.AttendanceImplDb;
import libs.Seminar;
import libs.Student;
import libs.StudentSorter;
import libs.Subject;

/**
 *  Tree data model class with Subject - Seminar group - Student hierarchy
 *
 * @author Dejvino
 */
public class SubjectTreeModel implements TreeModel {

    private Set<TreeModelListener> treeModelListeners = new LinkedHashSet<TreeModelListener>();
    private Object root = "";

    private Attendance attendance;

    public SubjectTreeModel() {
        attendance = new AttendanceImplDb();
    }

    public SubjectTreeModel(Attendance attendance) {
        this.attendance = attendance;
    }

    public Object getRoot() {
        return root;
    }

    private Object[] getChildArray(Object obj) {
        if(obj == null)
            throw new NullPointerException("object");
        // ROOT
        if(obj == root){
            Set set = attendance.getSubjects();
            if(set == null)
                return null;
            if(set.isEmpty())
                return null;
            LinkedList list = new LinkedList(set);
            java.util.Collections.sort(list, new Comparator<Subject>(){
                public int compare(Subject s1, Subject s2) {
                    return s1.getCode().compareTo(s2.getCode());
                }
            });
            return list.toArray();
        }
        // SUBJECT
        if(Subject.class == obj.getClass()){
            Set set = attendance.getSeminars((Subject)obj);
            if(set == null)
                return null;
            if(set.isEmpty())
                return null;
            LinkedList list = new LinkedList(set);
            java.util.Collections.sort(list, new Comparator<Seminar>(){
                public int compare(Seminar s1, Seminar s2) {
                    return s1.getNumber() - s2.getNumber();
                }
            });
            return list.toArray();
        }
        // SEMINAR
        if(Seminar.class == obj.getClass()){
            return new StudentSorter(attendance.getStudents((Seminar)obj)).getArray();
        }
        // STUDENT and ELSE
        return null;
    }

    public Object getChild(Object obj, int index) {
        if(obj == null)
            throw new NullPointerException("object");
        Object[] array = getChildArray(obj);
        if(array != null && index < array.length)
            return array[index];
        return null;
    }

    public int getChildCount(Object obj) {
        if(obj == null)
            throw new NullPointerException("object");
        Object[] array = getChildArray(obj);
        if(array != null)
            return array.length;
        return 0;
    }

    public boolean isLeaf(Object obj) {
        if(Student.class == obj.getClass())
            return true;
        return false;
    }

    public void valueForPathChanged(TreePath arg0, Object arg1) {
        for(TreeModelListener listener : treeModelListeners)
        {
            listener.treeStructureChanged(new TreeModelEvent(this, arg0));
        }
    }

    public int getIndexOfChild(Object arg0, Object arg1) {
        if(arg0 == null || arg1 == null)
            return -1;
        Object[] array = getChildArray(arg0);
        for(int i=0; i<array.length; i++){
            if(array[i] == arg1)
                return i;
        }
        return -1;
    }

    public void addTreeModelListener(TreeModelListener arg0) {
        treeModelListeners.add(arg0);
    }

    public void removeTreeModelListener(TreeModelListener arg0) {
        treeModelListeners.remove(arg0);
    }
}
